package com.q3d.demo.svc.hello.config.remote.helloworld;

import java.util.Optional;

import javax.annotation.PostConstruct;

import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.cloud.nacos.NacosConfigProperties;
import com.alibaba.nacos.api.config.ConfigChangeEvent;
import com.alibaba.nacos.api.config.ConfigChangeItem;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.listener.impl.AbstractConfigChangeListener;

import lombok.extern.slf4j.Slf4j;

@Slf4j /** Lombok 的 Logger 注解 */
@Component /** 注入组件 */
/**
 * @author 叶湘 ( weixin:yexiang841, email:yexiang841@qq.com )
 */
public class ConfigHelloWorldManager {

        @Autowired
        private ConfigHelloWorldModel configHelloWorldModel;

        @Value(value = "${spring.application.name}") /** 读取配置文件（或远程配置）数据 */
        public String applicationName;

        @Autowired
        private ModelMapper modelMapper;

        @Autowired
        NacosConfigManager nacosConfigManager;

        @Autowired
        NacosConfigProperties nacosConfigProperties;

        @PostConstruct
        public void init() {
                try {
                        /**
                         * 当 Nacos 中的配置发生变更时，
                         * ConfigHelloWorldModel 因其 @ConfigurationProperties 注解已经自动变更，
                         * 这里只是为了抓取变更事件，其实只是打了日志。
                         */
                        nacosConfigManager.getConfigService()
                                        .addListener(
                                                        applicationName + "-helloworld.yaml",
                                                        "group-" + applicationName,
                                                        new AbstractConfigChangeListener() {
                                                                @Override
                                                                public void receiveConfigChange(
                                                                                final ConfigChangeEvent event) {
                                                                        String source = Optional.ofNullable(
                                                                                        event.getChangeItem(
                                                                                                        "config.helloworld.source"))
                                                                                        .map(ConfigChangeItem::getNewValue)
                                                                                        .orElse(null);
                                                                        String text = Optional.ofNullable(
                                                                                        event.getChangeItem(
                                                                                                        "config.helloworld.text"))
                                                                                        .map(ConfigChangeItem::getNewValue)
                                                                                        .orElse(null);
                                                                        String num = Optional.ofNullable(
                                                                                        event.getChangeItem(
                                                                                                        "config.helloworld.num"))
                                                                                        .map(ConfigChangeItem::getNewValue)
                                                                                        .orElse(null);
                                                                        log.info("receiveConfigChange"
                                                                                        + " source: " + source
                                                                                        + " text: " + text
                                                                                        + " num:" + num);
                                                                }
                                                        });

                } catch (NacosException e) {
                        log.warn("init : " + e.getMessage());
                }
        }

        /**
         * 获取配置中心所有字段的值
         *
         * @return ConfigHelloWorldDto
         */
        public ConfigHelloWorldDto getAll() {
                return this.convertToDto(configHelloWorldModel);
        }

        /**
         * 获取配置中心 source 字段的值
         *
         * @return String
         */
        public String getSource() {
                return configHelloWorldModel.getSource();
        }

        /**
         * 获取配置中心 text 字段的值
         *
         * @return String
         */
        public String getText() {
                return configHelloWorldModel.getText();
        }

        /**
         * 获取配置中心 num 字段的值
         *
         * @return Integer
         */
        public Integer getNum() {
                return configHelloWorldModel.getNum();
        }

        /**
         * 从 Model 转换成 DTO
         *
         * @param model
         * @return DTO
         */
        ConfigHelloWorldDto convertToDto(ConfigHelloWorldModel model) {
                return modelMapper.map(model, ConfigHelloWorldDto.class);
        }

        /**
         * 从 DTO 转换成 Model
         *
         * @param dto
         * @return Model
         */
        ConfigHelloWorldModel convertToModel(ConfigHelloWorldDto dto) {
                return modelMapper.map(dto, ConfigHelloWorldModel.class);
        }

}
